Register.php

<?php

namespace Tlf\User\Gui;

class Register extends \Tlf\User\GuiTester {


// Paths
// 1: view register form
// 2: submit register form, create new user
// 3: submit register form, user exists
// 4: submit register form, invalid confirmation email
// 5: submit register form, invalid password
// 6: submit register form, invalid confirm password
// 7: submit register form, invalid email 
// 8: What happens if a user registered but didn't finish registration & now their reg code is expired?
    // Maybe reset password is sufficient for getting them a new code? Hmmm.
    // Or do they need to re-register? Hmmm.

    public function testCompleteExpiredRegistration(){
        // echo "Test not yet implemented.";
        // will this require re-registration?
        // or maybe a password reset?
        // or maybe a different form?
        //
        
        $lib = new \Tlf\User\Lib($this->pdo());
        $email = 'reed@complete.registration.expiredcode';
        $user = $lib->user_from_email($email);
        $user->register('some password');
        $code = $user->new_code('registration');
        $lildb = new \Tlf\LilDb($this->pdo());
        $rows = $lildb->updateWhere('code',['expires_at'=> '2022-01-01'], ['code'=>$code]);
        // var_dump($rows);
        // exit;

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_active());

        $response = $this->get('/user/complete.registration.'.$code.'/',
            ['test_spoof_ip'=>'complete.expired.registration']
        );

        echo $response;

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_active());

        $reset_password_url = '/user/reset-password/';
        $login_url = '/user/login/';
        $this->str_contains($response,
            "The code you submitted is not valid. If you've just clicked a link in your email, you may already be registered and can <a href=\"$login_url\">log in</a> or the code may have expired & you can <a href=\"$reset_password_url\">reset your password</a> to finish registration."
        );
        
        $this->str_not_contains($response,
            'Registration complete!',
            '<a href="/user/login/">Login here!</a>'
        );
    }

    public function testCompleteRegistration(){
        $lib = new \Tlf\User\Lib($this->pdo());
        $email = 'reed@complete.registration';
        $user = $lib->user_from_email($email);
        $user->register('some password');
        $code = $user->new_code('registration');


        $this->is_false($user->is_active());

        $response = $this->get('/user/complete.registration.'.$code.'/',
            ['test_spoof_ip'=>'complete.good.registration']
        );

        // echo $response;
        // exit;

        $user = $lib->user_from_email($email);
        $this->is_true($user->is_active());

        $this->str_contains($response,
            'Registration complete!',
            '<a href="/user/login/">Login here!</a>'
        );
    }

    public function testInvalidEmail(){
        $email = 'reed-invalid-email';
        $password = 'Abcd1234!@';
        $lib = new \Tlf\User\Lib($this->pdo());
    
        $response = $this->post('/user/register/',
            ['email'=>$email,
            'email_confirm'=>$email,
            'password'=>$password,
            'password_confirm'=>$password,
             'test_spoof_ip'=>'register.invalid.email',
            ]
        );

        $this->str_contains(
            $response,
            "'$email' is not a valid email address. Please try again.",
            '<form method="POST" action="/user/register/">',
            // include a message to "let us know if your email is, in fact REAL & we have a bug"
                // bc php filter_var() may have issues with rfc compatability,
                    // as noted on the php website by some users
        );

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_registered());
        $this->is_false($user->is_active());
        $ldb = new \Tlf\LilDb($this->pdo());
        $rows = $ldb->select('code', ['user_id'=>$user->id]);
        $this->test("Ensure a new code was not created during POST.");
        $this->is_true(count($rows)==0);
    }
    
    public function testInvalidConfirmationPassword(){
        $email = 'reed@register.passwordmismatch';
        $password = 'Abcd1234!@';
        $lib = new \Tlf\User\Lib($this->pdo());
    
        $response = $this->post('/user/register/',
            ['email'=>$email,
            'email_confirm'=>$email,
            'password'=>$password,
            'password_confirm'=>$password.'O',
             'test_spoof_ip'=>'register.invalid.confirmpassword',
            ]
        );

        $this->str_contains(
            $response,
            'The confirmation password you entered does not match. Please try again.',
            '<form method="POST" action="/user/register/">',
        );

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_registered());
        $this->is_false($user->is_active());
        $ldb = new \Tlf\LilDb($this->pdo());
        $rows = $ldb->select('code', ['user_id'=>$user->id]);
        $this->test("Ensure a new code was not created during POST.");
        $this->is_true(count($rows)==0);

    }

    public function testInvalidPassword(){
        $email = 'reed@register.passwordinvalid';
        $password = 'abcd123456';
        $lib = new \Tlf\User\Lib($this->pdo());
    
        $response = $this->post('/user/register/',
            ['email'=>$email,
            'email_confirm'=>$email,
            'password'=>$password,
            'password_confirm'=>$password,
             'test_spoof_ip'=>'register.invalid.password',
            ]
        );

        $this->str_contains(
            $response,
            'The password you entered does not meet our minimum security requirements. Please try again.',
            '<form method="POST" action="/user/register/">',
        );

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_registered());
        $this->is_false($user->is_active());
        $ldb = new \Tlf\LilDb($this->pdo());
        $rows = $ldb->select('code', ['user_id'=>$user->id]);
        $this->test("Ensure a new code was not created during POST.");
        $this->is_true(count($rows)==0);
    }

    public function testInvalidConfirmationEmail(){

        $email = 'reed@register.emailconfirmissue';
        $password = 'Abcd1234!@';
        $lib = new \Tlf\User\Lib($this->pdo());

        $response = $this->post('/user/register/',
            ['email'=>$email,
            'email_confirm'=>'reed@wrongconfirm.email',
            'password'=>$password,
            'password_confirm'=>$password,
             'test_spoof_ip'=>'register.confirmationemail.invalid',
            ]
        );

        // echo $response;
        // exit;

        $this->str_contains(
            $response,
            'The confirmation email you entered does not match. Please try again.',
            '<form method="POST" action="/user/register/">',
        );

        $user = $lib->user_from_email($email);
        $this->is_false($user->is_registered());
        $this->is_false($user->is_active());
        $ldb = new \Tlf\LilDb($this->pdo());
        $rows = $ldb->select('code', ['user_id'=>$user->id]);
        $this->test("Ensure a new code was not created during POST.");
        $this->is_true(count($rows)==0);
    }

    public function testUserExists(){
        $email = 'reed@register.exists';
        $password = 'Abcd1234!@';
        $lib = new \Tlf\User\Lib($this->pdo());
    
        $user = $lib->user_from_email($email);
        $code = $user->register($password);

        $response = $this->post('/user/register/',
            ['email'=>$email,
            'email_confirm'=>$email,
            'password'=>$password,
            'password_confirm'=>$password,
             'test_spoof_ip'=>'register.user.exists',
            ]
        );

        $this->str_contains(
            $response,
            "An email has been sent to $email. Please check your email to finish registration."
        );

        $this->str_not_contains(
            $response,
            '<form method="POST" action="/user/register/">',
        );

        $user = $lib->user_from_email($email);
        $this->is_true($user->is_registered());
        $this->is_false($user->is_active());
        $ldb = new \Tlf\LilDb($this->pdo());
        $rows = $ldb->select('code', ['user_id'=>$user->id]);
        $this->test("Ensure a new code was not created during POST.");
        $this->is_true(count($rows)==0);


        $email = file_get_contents($this->file('test/Server/email-body-out.txt'));
        // echo "\n\n$email";
        // exit;
        // $this->is_false(true);
        // echo "this test is not complete. it needs to validate email.";
        $url = 'http://create.localhost/user/login/';
        $target = "Somebody tried to register an account with your email address, "
            ."but you already have an account with us. Log in at "
            ."<a href=\"$url\">$url</a>";

        $this->compare($target, $email);
    }

    public function testCreateUser(){
        // POST /user/register
        $email = 'reed@register.new';
        $password = 'Abcd1234!@';

        $response = $this->post('/user/register/',
            ['email'=>$email,
             'email_confirm'=>$email,
             'password'=>$password,
             'password_confirm'=>$password,
             'test_spoof_ip'=>'register.create.user',
            ]
        );

        // echo $response;
        // exit;

        ////////
        // validate response
        ////////
        echo $response;
        echo "\n\n";
        $this->str_contains(
            $response,
            "An email has been sent to $email. Please check your email to finish registration.",
        );
        $this->str_not_contains(
            $response,
            '<form method="POST" action="/user/register/">',
        );


        ////////
        // validate user state
        ////////
        $lib = new \Tlf\User\Lib($this->pdo());
        $ldb = new \Tlf\LilDb($this->pdo());



        ////////
        // validate sent email
        ////////
        $user = $lib->user_from_email($email);
        $code_rows = $ldb->select('code',['user_id'=>$user->id]);
        $code = $code_rows[0]['code'];

        $body = file_get_contents($this->file('test/Server/email-body-out.txt'));
        $target_url = 'http://create.localhost/user/complete.registration.'.$code.'/';

        $this->compare(
            "To complete registration, visit <a href=\"$target_url\">$target_url</a>",
            $body,
        );

        $path = parse_url($target_url, PHP_URL_PATH);
        $response = $this->get($path);

        // then i need to get the user & make sure there is a valid registration code
        $user = $lib->user_from_email($email);
        $this->is_true($user->is_registered());
        $this->is_true($user->is_active());
        $this->is_string($user->password_login('Abcd1234!@'));

        // $this->is_true($user->activate($code));
        // $this->is_true($user->is_active());
            
    }

    public function testViewForm(){
        $response = $this->get('/user/register/');
        $this->str_contains(
            $response,
            '<form method="POST" action="/user/register/">',
        );

        echo $response;
    }

}